package com.hongji.lms5xxcommunicator.opc.util;

import com.hongji.lms5xxcommunicator.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.milo.opcua.sdk.client.OpcUaClient;
import org.eclipse.milo.opcua.stack.core.Identifiers;
import org.eclipse.milo.opcua.stack.core.types.builtin.*;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger;
import org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort;
import org.eclipse.milo.opcua.stack.core.types.enumerated.TimestampsToReturn;

import java.util.concurrent.TimeUnit;

@Slf4j
public class OpcNodeResolver {

    /** 统一解析：支持 nsu=URI;i=… / ns=4;i=… / ns=4;id=…（id 自动转 i） */
    public NodeId resolveFlexible(OpcUaClient client, String raw) {
        if (raw == null || raw.trim().isEmpty()) {
            throw new IllegalArgumentException("空的 NodeId 字符串");
        }
        String s = raw.trim().replace("id=", "i=");
        try {
            if (s.startsWith("nsu=")) {
                ExpandedNodeId en = ExpandedNodeId.parse(s);
                String nsUri = en.getNamespaceUri();
                UShort idx = findNamespaceIndex(client, nsUri);

                Object id = en.getIdentifier();
                if (id instanceof UInteger)   return new NodeId(idx, (UInteger) id);
                if (id instanceof String)     return new NodeId(idx, (String) id);
                if (id instanceof ByteString) return new NodeId(idx, (ByteString) id);
                if (id instanceof java.util.UUID) return new NodeId(idx, (java.util.UUID) id);
                throw new IllegalArgumentException("不支持的标识类型: " + id);
            }
            return NodeId.parse(s); // ns=4;i=368
        } catch (Throwable t) {
            // 兜底：你已有的兼容方法
            return Utils.parseFlexibleNodeId(raw);
        }
    }

    /** 读取 Server_NamespaceArray，找 URI 对应索引（兼容各版本 Milo） */
    public UShort findNamespaceIndex(OpcUaClient c, String nsUri) throws Exception {
        DataValue dv = c.readValue(0.0, TimestampsToReturn.Neither, Identifiers.Server_NamespaceArray)
                .get(5, TimeUnit.SECONDS);
        Object v = (dv.getValue() != null) ? dv.getValue().getValue() : null;

        String[] arr;
        if (v instanceof String[]) {
            arr = (String[]) v;
        } else if (v instanceof Object[]) {
            Object[] obj = (Object[]) v;
            arr = new String[obj.length];
            for (int i = 0; i < obj.length; i++) arr[i] = String.valueOf(obj[i]);
        } else {
            throw new IllegalStateException("无法读取 NamespaceArray: " + v);
        }

        for (int i = 0; i < arr.length; i++) if (nsUri.equals(arr[i])) return UShort.valueOf(i);
        throw new IllegalArgumentException("Namespace 未注册: " + nsUri);
    }
}
